home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / vol16n12.zip / IPC.ZIP / PSERVER.ZIP / PSVRDLG.CPP < prev    next >
C/C++ Source or Header  |  1997-02-13  |  5KB  |  221 lines

  1. // PSvrDlg.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include <stdlib.h>
  6.  
  7. #include "PServer.h"
  8. #include "PSvrDlg.h"
  9.  
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15.  
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CPServerDlg dialog
  18.  
  19. CPServerDlg::CPServerDlg(CWnd* pParent /*=NULL*/)
  20.     : CDialog(CPServerDlg::IDD, pParent)
  21. {
  22.     //{{AFX_DATA_INIT(CPServerDlg)
  23.     //}}AFX_DATA_INIT
  24.     m_hIcon = AfxGetApp()->LoadStandardIcon(IDI_WINLOGO);
  25.     m_hPipe == NULL;
  26. }
  27.  
  28. void CPServerDlg::DoDataExchange(CDataExchange* pDX)
  29. {
  30.     CDialog::DoDataExchange(pDX);
  31.     //{{AFX_DATA_MAP(CPServerDlg)
  32.     DDX_Control(pDX, IDC_STATUS, m_wndStatus);
  33.     DDX_Control(pDX, IDC_PROGRESS, m_wndProgress);
  34.     //}}AFX_DATA_MAP
  35. }
  36.  
  37. BEGIN_MESSAGE_MAP(CPServerDlg, CDialog)
  38.     //{{AFX_MSG_MAP(CPServerDlg)
  39.     ON_WM_PAINT()
  40.     ON_WM_QUERYDRAGICON()
  41.     ON_WM_CREATE()
  42.     ON_WM_CLOSE()
  43.     //}}AFX_MSG_MAP
  44.     ON_MESSAGE (WM_USER_UPDATE, OnUserUpdate)
  45. END_MESSAGE_MAP()
  46.  
  47. /////////////////////////////////////////////////////////////////////////////
  48. // CPServerDlg message handlers
  49.  
  50. BOOL CPServerDlg::OnInitDialog()
  51. {
  52.     CDialog::OnInitDialog();
  53.  
  54.     SetIcon(m_hIcon, TRUE);            // Set big icon
  55.     SetIcon(m_hIcon, FALSE);        // Set small icon
  56.     
  57.     //
  58.     // Initialize the progress control.
  59.     //
  60.     m_wndProgress.SetRange (0, 10);
  61.     m_wndProgress.SetPos (0);
  62.  
  63.     //
  64.     // Start a background thread.
  65.     //
  66.     PIPEINFO* pInfo = new PIPEINFO;
  67.     pInfo->hPipe = m_hPipe;
  68.     pInfo->hWnd = m_hWnd;
  69.  
  70.     AfxBeginThread (ThreadFunc, pInfo);
  71.  
  72.     return TRUE;
  73. }
  74.  
  75. void CPServerDlg::OnPaint() 
  76. {
  77.     if (IsIconic())
  78.     {
  79.         CPaintDC dc(this);
  80.  
  81.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  82.  
  83.         // Center icon in client rectangle
  84.         int cxIcon = GetSystemMetrics(SM_CXICON);
  85.         int cyIcon = GetSystemMetrics(SM_CYICON);
  86.         CRect rect;
  87.         GetClientRect(&rect);
  88.         int x = (rect.Width() - cxIcon + 1) / 2;
  89.         int y = (rect.Height() - cyIcon + 1) / 2;
  90.  
  91.         // Draw the icon
  92.         dc.DrawIcon(x, y, m_hIcon);
  93.     }
  94.     else
  95.     {
  96.         CDialog::OnPaint();
  97.     }
  98. }
  99.  
  100. HCURSOR CPServerDlg::OnQueryDragIcon()
  101. {
  102.     return (HCURSOR) m_hIcon;
  103. }
  104.  
  105. int CPServerDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  106. {
  107.     if (CDialog::OnCreate(lpCreateStruct) == -1)
  108.         return -1;
  109.     
  110.     //
  111.     // Create a named pipe.
  112.     //
  113.     m_hPipe = ::CreateNamedPipe (
  114.         "\\\\.\\pipe\\ipcdemo",            // Pipe name
  115.         PIPE_ACCESS_OUTBOUND,            // Write access only
  116.         PIPE_TYPE_BYTE | PIPE_NOWAIT,    // Write bytes, no waiting
  117.         1,                                // One instance at a time, please
  118.         0,                                // Output buffer size (bytes)
  119.         0,                                // Input buffer size (bytes)
  120.         0,                                // Timeout value (milliseconds)
  121.         NULL                            // Use default security descriptor
  122.     );
  123.  
  124.     //
  125.     // Check for failures.
  126.     //
  127.     if (m_hPipe == INVALID_HANDLE_VALUE) {
  128.         MessageBox ("Unable to create a named pipe.", "Error",
  129.             MB_OK | MB_ICONSTOP);
  130.         return -1;
  131.     }    
  132.  
  133.     if (m_hPipe == NULL) {
  134.         MessageBox ("Windows 95 doesn't support named pipe servers. " \
  135.             "This application must be run under Windows NT.", "Error",
  136.             MB_OK | MB_ICONSTOP);
  137.         return -1;
  138.     }    
  139.  
  140.     //
  141.     // Seed the random number generator and return.
  142.     //
  143.     srand((int) ::GetCurrentTime ());
  144.     return 0;
  145. }
  146.  
  147. void CPServerDlg::OnClose() 
  148. {
  149.     //
  150.     // Close the pipe handle before shutting down.
  151.     //
  152.     if ((m_hPipe != NULL) && (m_hPipe != INVALID_HANDLE_VALUE)) {
  153.         ::CloseHandle (m_hPipe);
  154.         m_hPipe = NULL;
  155.     }    
  156.     CDialog::OnClose();
  157. }
  158.  
  159. LONG CPServerDlg::OnUserUpdate (UINT wParam, LONG lParam)
  160. {
  161.     //
  162.     // Update the display.
  163.     //
  164.     m_wndProgress.SetPos ((int) wParam);
  165.     m_wndStatus.SetWindowText (lParam ? "Connected" : "Not connected");
  166.     return 0;
  167. }
  168.  
  169. /////////////////////////////////////////////////////////////////////////////
  170. // Global functions
  171.  
  172. UINT ThreadFunc (LPVOID pParam)
  173. {
  174.     static BOOL bDisconnect = FALSE;
  175.  
  176.     PIPEINFO* pInfo = (PIPEINFO*) pParam;
  177.     HANDLE hPipe = pInfo->hPipe;
  178.     HWND hWnd = pInfo->hWnd;
  179.     delete pInfo;
  180.  
  181.     BYTE val;
  182.     DWORD dwBytesWritten;
  183.  
  184.     while (TRUE) {
  185.         val = rand () % 11;
  186.         if (IsClientConnected (hPipe)) {
  187.             //
  188.             // If a client process is connected, write a value to it
  189.             // through the pipe and update our own display.
  190.             //
  191.             ::WriteFile (hPipe, &val, 1, &dwBytesWritten, NULL);
  192.             ::PostMessage (hWnd, WM_USER_UPDATE, (WPARAM) val, 1);
  193.             bDisconnect = TRUE;
  194.         }
  195.         else {
  196.             //
  197.             // Otherwise, simply update our display. If ::DisconnectNamedPipe
  198.             // hasn't been called since the client process disconnected, call
  199.             // it now so other clients can attach later.
  200.             //
  201.             ::PostMessage (hWnd, WM_USER_UPDATE, (WPARAM) val, 0);
  202.             if (bDisconnect) {
  203.                 ::DisconnectNamedPipe (hPipe); // Let other clients connect
  204.                 bDisconnect = FALSE;
  205.             }
  206.         }
  207.         ::Sleep (1000);    // Pause for 1 second
  208.     }
  209.     return 0;
  210. }
  211.  
  212. BOOL IsClientConnected (HANDLE hPipe)
  213. {
  214.     OVERLAPPED olStruct;
  215.     ::ZeroMemory (&olStruct, sizeof (OVERLAPPED));
  216.  
  217.     ::ConnectNamedPipe (hPipe, &olStruct);
  218.  
  219.     return (::GetLastError () == ERROR_PIPE_CONNECTED) ? TRUE : FALSE;
  220. }
  221.